/*
  OLED SSD1306
*/
#ifndef SSD1306_H
#define SSD1306_H

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width,  in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // create SSD1306 display object connected to I2C

String tempString;

// Dog trot animation frames-  ascii art
const char *dogFrames[] = {
    "\x20\x20\x20\x20\x20\x20\x20 / \\__\n\x20\x20\x20\x20\x20\x20\x20(    @\\___\n\x20\x20\x20\x20\x20\x20\x20/         O\n\x20\x20\x20\x20\x20/   (_____/\n\x20\x20\x20\x20\x20/_____/   ",
    "\x20\x20\x20\x20\x20\x20\x20 / \\__\n\x20\x20\x20\x20\x20\x20\x20(    @\\___\n\x20\x20\x20\x20\x20\x20\x20/         O\n\x20\x20\x20\x20\x20\\   (_____/\n\x20\x20\x20\x20\x20\\_____\\   ",
    "\x20\x20\x20\x20\x20\x20\x20   / \\__\n\x20\x20\x20\x20\x20\x20\x20  (    @\\___\n\x20\x20\x20\x20\x20\x20\x20 /         O\n\x20\x20\x20\x20\x20\ /   (_____/\n\x20\x20\x20\x20\x20/_____/    ",
    "\x20\x20\x20\x20\x20\x20\x20   / \\__\n\x20\x20\x20\x20\x20\x20\x20  (    @\\___\n\x20\x20\x20\x20\x20\x20\x20 /         O\n\x20\x20\x20\x20\x20\x20\x20\\   (_____/\n\x20\x20\x20\x20\x20\x20\x20\\_____\\    "};

// dog Frames 非阻塞动画
unsigned long frameDelay = 100;
unsigned long prevAnimTime = 0;
int currentFrame = 0;
int totalFrames = 4;

// Eye parameters
const int eyeRadius = 20;
const int pupilRadius = 8;
const int eyeSpacing = 60;
int eyeX = SCREEN_WIDTH / 2 - eyeSpacing / 2;
int eyeY = SCREEN_HEIGHT / 2;
unsigned long eyes_movement_delay = 100;

void drawEyes()
{
  oled.clearDisplay();
  // Draw left eye
  oled.fillCircle(SCREEN_WIDTH / 2 - eyeSpacing / 2, SCREEN_HEIGHT / 2, eyeRadius, WHITE);
  // Draw right eye
  oled.fillCircle(SCREEN_WIDTH / 2 + eyeSpacing / 2, SCREEN_HEIGHT / 2, eyeRadius, WHITE);
  // Draw pupils (looking at the same point)
  int pupilOffsetX = map(eyeX, 0, SCREEN_WIDTH, -eyeRadius + pupilRadius, eyeRadius - pupilRadius) + 5;
  int pupilOffsetY = map(eyeY, 0, SCREEN_HEIGHT, -eyeRadius + pupilRadius, eyeRadius - pupilRadius);
  // Left pupil
  oled.fillCircle(
      SCREEN_WIDTH / 2 - eyeSpacing / 2 + pupilOffsetX,
      SCREEN_HEIGHT / 2 + pupilOffsetY,
      pupilRadius, BLACK);
  // Right pupil
  oled.fillCircle(
      SCREEN_WIDTH / 2 + eyeSpacing / 2 + pupilOffsetX,
      SCREEN_HEIGHT / 2 + pupilOffsetY,
      pupilRadius, BLACK);
  oled.display();
}

void updateTrotAnimation()
{
  unsigned long currentMillis = millis();
  if (currentMillis - prevAnimTime > frameDelay)
  {
    prevAnimTime = currentMillis;
    currentFrame = (currentFrame + 1) % totalFrames;
    oled.clearDisplay();
    oled.setTextSize(2.5); // text size
    oled.setCursor(6, 5);
    oled.println("DoG");
    oled.setTextSize(1); // text size
    oled.setCursor(00, 20);
    oled.print(dogFrames[currentFrame]);
    oled.display();
  }
}

void oledDisplayCenter(String text)
{
  int16_t x1;
  int16_t y1;
  uint16_t width = 0;
  uint16_t height = 0;
  oled.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);
  // display on horizontal and vertical center
  oled.clearDisplay(); // clear display
  oled.setCursor((SCREEN_WIDTH - width) / 2, (SCREEN_HEIGHT - height) / 2);
  oled.println(text); // text to display
  oled.display();
}

void setup_ssd1306()
{
  // initialize OLED display with address 0x3C for 128x64
  if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C))
  {
    Serial.println(F("SSD1306 allocation failed"));
    while (true)
      ;
  }
  // wait for initializing
  delay(1000);
  oled.clearDisplay();      // clear display
  oled.setTextColor(WHITE); // text color
  // oled.setTextSize(3);       // text size
  // oledDisplayCenter("DoG");
  // tempString.reserve(10);  // to avoid fragmenting memory when using String
  // prevAnimTime = 0;
  for (int j = 0; j < 6; j++)
  {
    for (int i = 0; i < 4; i++)
    {
      oled.clearDisplay();
      oled.setTextSize(2.5); // text size
      oled.setCursor(6, 5);
      oled.println("DoG");
      oled.setTextSize(1); // text size
      oled.setCursor(00, 20);
      oled.print(dogFrames[i]);
      oled.display();
      delay(frameDelay);
    }
  };
  delay(1000);
}

void loop_ssd1306()
{
  //  updateTrotAnimation();
  drawEyes();
  // Simulate eye movement by changing gaze direction occasionally
  static unsigned long lastMoveTime = 0;
  unsigned long currentMillis = millis();
  if (currentMillis - lastMoveTime > eyes_movement_delay)
  {
    eyeX = SCREEN_WIDTH / 2 - eyeSpacing / 2 + random(-10, 10);
    eyeY = SCREEN_HEIGHT / 2 + random(-5, 5);
    lastMoveTime = currentMillis;
  }
}

#endif /* SSD1306_H */